/*
 * COPYRIGHT:	2010 Christopher Smith, licenced under the GNU GPL v2; see COPYING in the top level directory
 * PROJECT:		sdedit
 * FILE:		sdedit cppstruct.cpp
 * PURPOSE:		C++ versions of sdedit structures, utilizing automatic containers
 *				includes C version of structures in the cstruct namespace
 */

#include "sdedit struct.h"

namespace cstruct
{
#include "sdedit cstruct.h"
}

template <> FORCEINLINE size_t auto_szpod_length(GUID const *x)
{
	return sizeof(GUID);
}

FORCEINLINE USHORT GetSidLength(SID const *x)
{
	return FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG) * x->SubAuthorityCount; //header + variable
}

template <> FORCEINLINE size_t auto_szpod_length(SID const *x)
{
	return GetSidLength(x);
}

template <> FORCEINLINE size_t auto_szpod_length(TOKEN_GROUPS const *x)
{
	return FIELD_OFFSET(TOKEN_GROUPS, Groups) + sizeof(SID_AND_ATTRIBUTES) * x->GroupCount; //header + variable
}

template <> FORCEINLINE size_t auto_szpod_length(wchar_t const *x)
{
	return wcslen(x) * sizeof(wchar_t) + sizeof(wchar_t);
}

template <> FORCEINLINE size_t auto_szpod_length(UNICODE_STRING const *x)
{
	return sizeof(UNICODE_STRING);
}

template <> FORCEINLINE size_t auto_szpod_length(ACE const *x)
{
	return max(sizeof(SDE_ACE_HEADER), x->Size);
}

template <> FORCEINLINE size_t auto_szpod_length(ACL const *x)
{
	return max(sizeof(ACL), x->AclSize);
}

template <> FORCEINLINE size_t auto_szpod_length(SECURITY_DESCRIPTOR_RELATIVE const *x)
{
	return max(SECURITY_DESCRIPTOR_MIN_LENGTH, RtlLengthSecurityDescriptor(x));
}

struct ACL_AND_STATE
{
	auto_szpod<ACL> Acl;
	ULONG State;
	ACL_AND_STATE() :
		State(0)
	{}
	operator cstruct::ACL_AND_STATE &() //binary equivalence
	{
		return ref_cast<cstruct::ACL_AND_STATE>(*this);
	}
};

struct SID_AND_STATE
{
	auto_szpod<SID> Sid;
	ULONG State;
	SID_AND_STATE() :
		State(0)
	{}
	operator cstruct::SID_AND_STATE &() //binary equivalence
	{
		return ref_cast<cstruct::SID_AND_STATE>(*this);
	}
};

struct RMBITS_AND_STATE
{
	UCHAR Bits;
	UCHAR Pad0;
	USHORT State;
	RMBITS_AND_STATE() :
		Bits(0),
		Pad0(0),
		State(0)
	{}
	operator cstruct::RMBITS_AND_STATE &() //binary equivalence
	{
		return ref_cast<cstruct::RMBITS_AND_STATE>(*this);
	}
};

struct SD_EDIT_STATE
{
	ULONG Version;
	ULONG State;
	ACL_AND_STATE Dacl; //discretionary ACL
	ACL_AND_STATE Sacl; //system ACL
	ACL_AND_STATE Lacl; //label ACL
	SID_AND_STATE Owner;
	SID_AND_STATE Group;
	RMBITS_AND_STATE RMBits;
	SD_EDIT_STATE() :
		Version(1),
		State(0)
	{}
	operator cstruct::SD_EDIT_STATE &() //binary equivalence
	{
		return ref_cast<cstruct::SD_EDIT_STATE>(*this);
	}
};

//see DN_QUERY_INHERITANCE_ACL in "sdedit cstruct.h"
struct DN_QUERY_INHERITANCE_ACL
{
	ACL_AND_STATE AclAndState;
};

//see DN_QUERY_DEFAULT_ACL in "sdedit cstruct.h"
struct DN_QUERY_DEFAULT_ACL
{
	ACL_AND_STATE AclAndState;
};

//see DN_QUERY_INHERITANCE_ES in "sdedit cstruct.h"
struct DN_QUERY_INHERITANCE_ES
{
	SD_EDIT_STATE Es;
};

//see DN_QUERY_DEFAULT_ES in "sdedit cstruct.h"
struct DN_QUERY_DEFAULT_ES
{
	SD_EDIT_STATE Es;
};